package com.qzw.security.service.service.impl;

import com.qzw.common.api.base.BaseException;
import com.qzw.common.data.BaseMysqlDao;
import com.qzw.common.service.BaseServiceImpl;
import com.qzw.security.api.model.Resource;
import com.qzw.security.api.query.ResourceQuery;
import com.qzw.security.api.service.IResourceService;
import com.qzw.security.service.dao.ResourceDao;
import com.qzw.security.service.entity.SysPermission;
import com.qzw.security.service.entity.SysResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.transaction.Transactional;
import java.util.*;

/**
 * @author ：quziwei
 * @date ：Created in 2020/6/2 11:55 上午
 * @description：
 */
@Service
@CacheConfig(cacheNames = "system")
public class ResourceServiceImpl extends BaseServiceImpl<Resource, SysResource,Integer, ResourceQuery> implements IResourceService {
    @Autowired
    private ResourceDao dao;

    private String[] allowMethod = new String[]{"ALL", "GET", "POST", "PUT", "DELETE"};


    @Override
    public Resource update(Resource model) {
        boolean allow = false;
        if (isNotEmpty(model.getMethod())) {
            for (String method : allowMethod) {
                if (method.equalsIgnoreCase(model.getMethod())) {
                    allow = true;
                }
            }
        }
        if (!allow) {
            throw new BaseException("资源方法不正确");
        }
        if (isNotEmpty(model.getId())) {
            Optional<SysResource> sysResource = dao.findById(model.getId());
            if (isNotEmpty(model.getPath()))
                sysResource.get().setResource(model.getResource());
            model = entity2model(dao.save(sysResource.get()));
        } else {
            model = entity2model(dao.save(model2Entity(model)));
        }
        return model;
    }

    @Override
    @Transactional
    public void permissionEdit(Integer resourceId, List<Integer> permissionIds) {
        Optional<SysResource> sysResource = dao.findById(resourceId);
        Set<SysPermission> permissions = new HashSet<>();
        sysResource.get().setPermissions(permissions);
        if (!CollectionUtils.isEmpty(permissionIds))
            for (Integer id : permissionIds) {
                SysPermission sysPermission = new SysPermission();
                sysPermission.setId(id);
                permissions.add(sysPermission);
            }
        dao.save(sysResource.get());
    }

    @Override
    @Transactional
    public Map<String, Set<String>> findResourcePermissions() {
        List<SysResource> sysResources = dao.findAll();
        Map<String, Set<String>> result = new HashMap<>();
        for (SysResource sysResource : sysResources) {
            Set<SysPermission> sysPermissions = sysResource.getPermissions();
            if (!CollectionUtils.isEmpty(sysPermissions)) {
                Set<String> permissions = new HashSet<>();
                result.put(sysResource.getResource(), permissions);
                for (SysPermission sysPermission : sysPermissions) {
                    permissions.add(sysPermission.getPermission());
                }
            }
        }
        return result;
    }

    @Override
    protected BaseMysqlDao<SysResource, Integer> getDao() {
        return dao;
    }

    @Override
    protected SysResource model2Entity(Resource model) {
        SysResource sysResource = null;
        if (!ObjectUtils.isEmpty(model)) {
            sysResource = new SysResource();
            sysResource.setId(model.getId());
            sysResource.setResource(model.getResource());
        }
        return sysResource;
    }

    @Override
    protected Resource entity2model(SysResource entity) {
        Resource resource = null;
        if (!ObjectUtils.isEmpty(entity)) {
            resource = new Resource();
            resource.setId(entity.getId());
            resource.setResource(entity.getResource());
        }
        return resource;
    }
}
